package com.bshark.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

public class JdbcPool {

	private static List<Connection> pool = new LinkedList<Connection>();
	private static int minConn = 10;
	private static int maxConn = 50;
	private static int curActive = 0;
	private static JdbcPool jp;

	public static JdbcPool getInstance() {
		if (jp == null) {
			jp = new JdbcPool();
		}
		return jp;
	}

	private JdbcPool() {
		initPool();
	}

	public void initPool() {
		for (int i = 0; i < minConn; i++) {
			try {
				pool.add(createConnection());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private Connection createConnection() throws Exception {
		String clazz = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@183.61.183.169:1521:orcl";
		String username = "ddz";
		String password = "ddz20130320";
		Connection conn = null;
		Class.forName(clazz);
		conn = DriverManager.getConnection(url, username, password);
		// ��֤l�ӳ��д�ŵ��Ƕ������ Proxy�õ���̬�������
		conn = (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[] { Connection.class }, new DynamicProxyHandler(conn));
		return conn;
	}

	public synchronized Connection getConnection() throws Exception {
		Connection conn = null;
		synchronized (pool) {
			if (pool.size() <= 0) {
				if (curActive <= maxConn) {
					conn = createConnection();// ����Ѿ��Ǵ�����
					curActive++;
				} else {
					Thread.sleep(50);
				}
			} else {
				conn = pool.remove(0);
				curActive++;
			}
		}
		return conn;
	}

	private class DynamicProxyHandler implements InvocationHandler {// �߼�������
		private Connection conn;

		private DynamicProxyHandler(Connection conn) {
			this.conn = conn;
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			if (method.getName() == "close") {
				synchronized (pool) {
					if (pool.size() > minConn) {
						try {
							conn.close();
							System.out.println("����ر�");
						} catch (SQLException e) {
							e.printStackTrace();
						}
					} else {
						conn = (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[] { Connection.class }, new DynamicProxyHandler(conn));
						pool.add(conn);
					}
				}
				curActive--;
				return null;
			}
			return method.invoke(conn, args);
		}

	}

	public static void main(String[] args) {
		try {
			long begin=System.currentTimeMillis();
			Connection conn = null;
			for (int i = 0; i < 1000; i++) {
				conn = JdbcPool.getInstance().getConnection();
				conn.close();
			}
			long end=System.currentTimeMillis();
			System.out.println("ʱ��:"+(end-begin)+"ms");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}